﻿//* Copyright(C) 2005-2012, all rights reserved.
//*
//* The following code is copyrighted and contains proprietary information
/* and trade secrets of Foxit Software Inc.      
**************************************************************************
*/

/**
* Annot插件类
*/



define(function (require, exports, module) {
    // var FXREADER = require('../../FXReader');
    var CPDF_Annot = FXREADER.PDFData.CPDF_Annot;
    var CAnnotFactory = FXREADER.CAnnotFactory;
    var CAnnot_PageEventHandler = require('./AnnotPageEvent');
    var CAnnot_MousePtHandler = require('./AnnotMousePtHandler');
    var CAnnot_DocViewEventHandler = require('./AnnotDocViewEventHandler');
    var CommonTools = FXREADER.Common;
    require("./CommentsAnnot.js");
    var AnnotDataJsonFmt =
    {
        PageIndex: "number",
        Annots: "annots"
    };

    FXREADER.CAnnotPlugin = function (pReaderApp) {
        var _pReaderApp = pReaderApp;
        //是否初始化完成;
        var _bInited = false;
        // 存储已经创建html的页面索引 ，格式为 :   页面索引：true/fase;
        var _PageAnnotCreatedList = {};
        var _PageAnnotUpdatedList = [];
        var _self = this;
        var _AnnotCanvasID = null;
        var _Language = _pReaderApp.GetLanguage();
        //当前需要绘制与popup连线的annot;
        var _curVisableRope = { nPageIndex: -1, nAnnotIndex: -1 };
        //绘制Rope所需常量
        var ROPE_SHAPE_FACTOR1 = 0.95;
        var ROPE_SHAPE_FACTOR2 = 0.05;
        var ROPE_PI = 3.141592653;
        var ROPE_THICKNESS = 28;




        //private methods
        function _Init(jsonAnnotData) {
            _AnnotCanvasID = pReaderApp.GetMainView().GetDocView().GetDocViewContainerID() + "_AnnotCanvas";
            var pPDFDoc = pReaderApp.GetPDFDoc();
            for (var i = 0; i < jsonAnnotData.length; i++) {
                var iPageNum = jsonAnnotData[i][AnnotDataJsonFmt.PageIndex];
                var pPDFPage = pPDFDoc.GetPage(iPageNum);
                var jsonAnnots = jsonAnnotData[i][AnnotDataJsonFmt.Annots];
                for (var j = 0; j < jsonAnnots.length; j++) {
                    var pAnnot = CAnnotFactory.CreateAnnot(jsonAnnots[j]);
                    pPDFPage.AddAnnot(pAnnot);
                    _AddGourpAnnot2Page(pAnnot, pPDFPage);

                }
            }
            _bInited = true;

            var pDocView = _pReaderApp.GetMainView().GetDocView();
            var visablePageRange = pDocView.GetDisplayPageRange();
            var jqPagesContainerDiv = $("#" + pDocView.GetDocViewContainerID());
            var pFirstPageView = pDocView.GetPageView(0);
            if (pFirstPageView != null && pFirstPageView.IsContentCreated()) {
                $("#" + pFirstPageView.GetPageContainerID()).parent().parent().append("<canvas class='vml' style='position:absolute;top:0px;left:0px' id='" + _AnnotCanvasID + "'></canvas>");
            }
            else {
                jqPagesContainerDiv.append("<canvas class='vml' style='position:absolute;top:0px;left:0px' id='" + _AnnotCanvasID + "'></canvas>");
            }
            var ScrollApi = pDocView.GetScrollApi();
            if (ScrollApi != null) {
                var CanvasElem = document.getElementById(_AnnotCanvasID);
                if (CanvasElem != null) {
                    uuClass.Canvas.InitCavansElement(CanvasElem);
                    //这里必须重新获取Canvas一次，否则下面的宽高无法赋值;
                    CanvasElem = document.getElementById(_AnnotCanvasID);
                    CanvasElem.width = jqPagesContainerDiv.width();
                    CanvasElem.height = jqPagesContainerDiv.height();
                }
            }

            var contentPaneHeight = jqPagesContainerDiv.height();
            var contentPanelWidth = jqPagesContainerDiv.width();
            var contentPanelOffset = jqPagesContainerDiv.offset();
            for (var i = visablePageRange.begin; i <= visablePageRange.end; i++) {
                _self.OnPageVisable(pReaderApp.GetMainView().GetDocView().GetPageView(i), contentPanelWidth, contentPaneHeight, contentPanelOffset);
            }

        }

        function _AddGourpAnnot2Page(annot, pPDFPage) {
            if (pPDFPage && annot && annot.GetType() == "Markup") {
                var nGroupAnnotCnt = annot.CountGroupAnnots();
                for (var k = 0; k < nGroupAnnotCnt; k++) {
                    var pGroupAnnot = annot.GetAnnotFromGroup(k);
                    pPDFPage.AddAnnot(pGroupAnnot);
                    _AddGourpAnnot2Page(pGroupAnnot, pPDFPage);
                }
            }
        }

        //根据Annot状态获取对应的图标路径
        function _GetImgUrlByAnnotState(state) {
            switch (state) {
                case "Accepted":
                    return "images/annot/accepted.png";
                    break;
                case "Rejected":
                    return "images/annot/rejected.png";
                    break;
                case "Cancelled":
                    return "images/annot/canceled.png";
                    break;
                case "Completed":
                    return "images/annot/completed.png";
                    break;
                default: return "about:blank";
            }
        }

        function _GetImgUrlByTextAnnotName(name) {
            switch (name) {
                case "Comment":
                    return "images/annot/comment.png";
                    break;
                case "Key":
                    return "images/annot/key.png";
                    break;
                case "Note":
                    return "images/annot/note.png";
                    break;
                case "Help":
                    return "images/annot/help.png";
                    break;
                case "NewParagraph":
                    return "images/annot/new_paragraph.png";
                    break;
                case "Paragraph":
                    return "images/annot/paragraph.png";
                    break;
                case "Insert":
                    return "images/annot/insert.png";
                    break;
                default: return "about:blank";
            }
        }

        function _CreateReplyChainHtmlContent(annot) {
            var replyChain = annot.GetReplyChain();
            var iReplyCnt = replyChain.length;
            var divStr = "";
            for (var j = 0; j < iReplyCnt; j++) {
                var reply = replyChain[j];
                var szTextColor = CommonTools.IsColorBlack(reply.GetColor()) ? "color:#fff;" : "color:#000;";
                //begin reply div
                divStr += "<div class='popup_child' style='position:relative;margin-bottom:5px;border-style:solid; border-width: 1px;border-color:" + reply.GetColor() + ";" + szTextColor + "'>";

                //begin title div
                divStr += "<div class='popup_child' style='position:relative;left:0px;top:0px;height:18px;overflow:hidden;background-color:" + reply.GetColor() + "'>";
                var tmpleft = 2;
                var annot_state = reply.GetStateList();
                if (annot_state.length > 0) {
                    var stateimg = "about:blank";
                    tmpleft += 18;
                    for (var k = 0; k < annot_state.length; k++) {
                        if (annot_state[k].GetStateMode() == "Review")
                            stateimg = _GetImgUrlByAnnotState(annot_state[k].GetState());
                    }

                    divStr += "<div class='popup_child' style='position:absolute;background-position: center center;height:16px;width:16px;left:2px;background-image:url(" + stateimg + ")'></div>";
                }

                var szReplayTitle = "Reply " + (j + 1);
                divStr += "<div class='popup_child' style='position:relative;left:" + tmpleft + "px;'><div style='position: relative;line-height:18px; float:left;background-color:" + reply.GetColor() + "'>" + CommonTools.htmlspecialchars(szReplayTitle) + "</div>";
                divStr += "<div class='popup_child' style='position:relative;margin-left:15px;float:left;background-color:" + reply.GetColor() + "'>" + CommonTools.Timestamp2DateString(reply.GetModifyDate(), CommonTools.AnnotTimeFormat) + "</div></div>";
                //end title div
                divStr += "</div>";

                divStr += "<div class='popup_child' style='position:relative;clear:both;padding-left:5px;padding-right:5px;both; left: 0px; top: 0px;'>";
                //可以用pre标签实现换行;
                divStr += "<div class='popup_child' style='clear:both;padding-top:2px;padding-bottom:2px;word-wrap: break-word; word-break: normal;color:#000'>" + CommonTools.htmlspecialchars(reply.GetContents()) + "</div>";
                divStr += _CreateReplyChainHtmlContent(reply);
                divStr += "</div>";


                divStr += "</div>";
            }
            return divStr;
        }
        
        function _QuadPointsToRectArray(quadPoints,annotType)
        {
        	if(quadPoints==null || quadPoints.length%8 != 0)
        		return null;
        	var rectArray = [];
        	for(var i=0; i<quadPoints.length; i+=8)
        	{
        		var rect = null;
        		if(annotType===FXREADER.PDFData.CommentAnnotType.COMMENTTYPE_HIGHLIGHT)
        		{
        			rect = new FXREADER.CPDF_Rect(quadPoints[i], quadPoints[i+7], quadPoints[i+2], quadPoints[i+1]);
        		}
        		else if(annotType===FXREADER.PDFData.CommentAnnotType.COMMENTTYPE_UNDERLINE)
        		{
        			var height =  Math.abs(quadPoints[i+1]-quadPoints[i+7]);
        			rect = new FXREADER.CPDF_Rect(quadPoints[i], quadPoints[i+7]+height/8, quadPoints[i+2], quadPoints[i+7]);
        		}
        		
        		FXREADER.RectUtils.Normalize(rect);
        		rectArray.push(rect);
        	}
        	return rectArray;
        }

        this.CreateAAnnotHtmlContent = function(pPageView, annot, nAnnotIndex) {
            if (annot == null || pPageView == null)
                return "";
            var pPDFPage = pPageView.GetPDFPage();
            var annotPDFRect = annot.GetRect();
            var annotDocRect = pPageView.PDF2Doc(annotPDFRect, true);
            var annotDivID = _self.GetAnnotDivID(pPageView, nAnnotIndex);
            //background:url(about:blank) 用来解决ie下背景透明的话，即使div的z-index处于高层，也无法捕获事件的问题； 也可以用1*1px透明图解决
            var annotDivStr = "";

            if (annot.GetType() == "Link") {
                var action = annot.GetAction();
                if (action != null) {
                    switch (action.GetActionType()) {
                        case "URI":
                            var uri = action.GetURI();
                            uri = uri.replace(/^\s*/g, "");
                            var uriTmp = uri.toLowerCase();
							var bHttp  = uriTmp.indexOf("http:") == 0 || uriTmp.indexOf("http:") == 0;
							var bHttps  = uriTmp.indexOf("https:") === 0 || uriTmp.indexOf("https:") == 0;
                            if (!bHttp && !bHttps)
                                uri = "http://" + uri;
                            annotDivStr = "<a  target='_blank' id='" + annotDivID + "' class='fwr_annot' style='left:" + annotDocRect.left + "px;top:" + annotDocRect.top + "px;width:" + FXREADER.RectUtils.Width(annotDocRect) + "px;height:"
                    + FXREADER.RectUtils.Height(annotDocRect) + "px;' page-index='" + pPageView.GetPageIndex() + "' annot-index='" + nAnnotIndex + "' href=\"" + uri + "\" title=\"" + uri + "\"></a>";
                            break;
                        case "GoTo":
                            annotDivStr = "<div id='" + annotDivID + "' class='fwr_annot' style='left:" + annotDocRect.left + "px;top:" + annotDocRect.top + "px;width:" + FXREADER.RectUtils.Width(annotDocRect) + "px;height:"
                    + FXREADER.RectUtils.Height(annotDocRect) + "px;' page-index='" + pPageView.GetPageIndex() + "' annot-index='" + nAnnotIndex + "'></div>";
                            break;
                        default: break;
                    }
                }
                else {
                    annotDivStr = "<div id='" + annotDivID + "' class='fwr_annot' style='left:" + annotDocRect.left + "px;top:" + annotDocRect.top + "px;width:" + FXREADER.RectUtils.Width(annotDocRect) + "px;height:"
						+ FXREADER.RectUtils.Height(annotDocRect) + "px;' page-index='" + pPageView.GetPageIndex() + "' annot-index='" + nAnnotIndex + "'></div>";
                }
            }
            else {
                annotDivStr = "<div id='" + annotDivID + "' class='fwr_annot' style='left:" + annotDocRect.left + "px;top:" + annotDocRect.top + "px;width:" + FXREADER.RectUtils.Width(annotDocRect) + "px;height:"
                    + FXREADER.RectUtils.Height(annotDocRect) + "px;' page-index='" + pPageView.GetPageIndex() + "' annot-index='" + nAnnotIndex + "'></div>";
            }
            //          szAnnotsHtml += annotDivStr;


            if (annot.GetType() === "Markup") {
            	var subType = annot.GetSubType();
            	if(subType == FXREADER.PDFData.CommentAnnotType.COMMENTTYPE_HIGHLIGHT
            			||subType == FXREADER.PDFData.CommentAnnotType.COMMENTTYPE_UNDERLINE)
            	{
            		var quadPoints = annot.GetQuadPoints();
            		var bUseQuad = false;
            		var annotShowDivID = "123";
  		          	var annotShowDivHtml = "<div id='" + annotShowDivID + "' style='z-index:7;'>";
            		if(quadPoints != null)
            		{
            			var quadRectArray = _QuadPointsToRectArray(quadPoints,subType);
            			if(quadRectArray != null)
            			{ 
            		          for (var i = 0; i < quadRectArray.length; i++) {
            		                var rect = quadRectArray[i];
            		                rect = pPageView.PDF2Doc(rect, true);
            		                annotShowDivHtml += "<div id='333' class='fwr_annot_highlight' style='background-color:"+annot.GetColor()+";left:" +
		                                 rect.left + "px;top:" + rect.top + "px;width:" + FXREADER.RectUtils.Width(rect) + "px;height:" + FXREADER.RectUtils.Height(rect) + "px' ></div>";  
            		          }
            		          bUseQuad = true;
            			}
            		}
            		if(!bUseQuad)
            		{
            			annotShowDivHtml += "<div id='333' class='fwr_text_highlight' style='left:" +
            			annotDocRect.left + "px;top:" + annotDocRect.top + "px;width:" + FXREADER.RectUtils.Width(annotDocRect) + "px;height:" + FXREADER.RectUtils.Height(annotDocRect) + "px' ></div>";
            		}
            		annotShowDivHtml += "</div>";
            		annotDivStr += annotShowDivHtml;
            	}

                var popup = annot.GetPopup();
                if (popup == null || annot.GetHeadAnnot() != null)
                    return annotDivStr;
                var popupDivID = _self.GetAnnotPopupDivID(pPageView, nAnnotIndex);
                var popupPDFRect = popup.GetRect();
                //注意参数bScale设为false;
                var popupDocRect = pPageView.PDF2Doc(popupPDFRect, false);
                if (popupDocRect.top < 0)
                    popupDocRect.top = 0;
                //这里不允许高度超过页面高度，主要是因为如果超出页面高度，在初始化滚动条的时候，会把这个层的高度计算在内，导致滚动条高度出现问题;
                if (popupDocRect.bottom > pPDFPage.GetPageHeight())
                    popupDocRect.bottom = pPDFPage.GetPageHeight();
                var pop_width = FXREADER.RectUtils.Width(popupDocRect);
                var pop_height = FXREADER.RectUtils.Height(popupDocRect);
                var displayStyle = "";
                if (popup.GetOpenState() === 0) {
                    displayStyle = "display:none;";
                }
                //begin popup
                var szTextColor = CommonTools.IsColorBlack(annot.GetColor()) ? "color:#fff;" : "";
                var popupdiv = "<div id='" + popupDivID + "' class='fwr_popup_annot' style='left:" + popupDocRect.left + "px;top:"
                        + popupDocRect.top + "px;width:" + pop_width + "px;height:"
                        + pop_height + "px;background-color:" + annot.GetColor() + ";" + displayStyle + szTextColor + "' page-index='" + pPageView.GetPageIndex()
                        + "' annot-index='" + nAnnotIndex + "'>";
                //begin top div  
                popupdiv += "<div class='popup_header' style='position:absolute;left:0px;top:0px;height:20px;width:100%;overflow:hidden'>";
                if (annot.GetSubType() == "Text") {
                    var annotTypeImg = _GetImgUrlByTextAnnotName(annot.GetTextAnnotName());
                    popupdiv += "<div class='popup_header' style='background-image:url(" + annotTypeImg + ");background-position: center center; background-repeat: no-repeat;  position: absolute; left:1px;top:3px;width:16px;height:16px'></div>";
                }
                popupdiv += "<div class='popup_header' style='position:relative;left:20px;width:" + (pop_width - 40) + "px'><div class='popup_child'  style='position: absolute; left: 0px; top: 2px;background-color:" + annot.GetColor() + "'>" + CommonTools.htmlspecialchars(annot.GetSubject()) + "</div>";
                popupdiv += "<div class='popup_header' style='position:absolute;top:2px;height:18px;right:1px;background-color:" + annot.GetColor() + "'>" + CommonTools.Timestamp2DateString(annot.GetModifyDate(), CommonTools.AnnotTimeFormat) + "</div></div>";
                popupdiv += "<div  title='" + _Language.Annot.ClosePopupAnnot + "' class='annot_close_btn' style='background-image:url(images/annot/popclose.png);background-position: center center; background-repeat: no-repeat; cursor: pointer; position: absolute; left:" + (pop_width - 20) + "px;width:20px;height:18px;'></div>";
                popupdiv += "</div>";
                //end top div 
                //title div
                popupdiv += "<div class='popup_header' style='position:absolute;left:0px;top:20px;height:20px;width:100%'>";
                var annot_state = annot.GetStateList();
                if (annot_state.length > 0) {
                    var stateimg = "about:blank";
                    for (var k = 0; k < annot_state.length; k++) {
                        if (annot_state[k].GetStateMode() == "Review")
                            stateimg = _GetImgUrlByAnnotState(annot_state[k].GetState());
                    }
                    popupdiv += "<div class='popup_header' style='position:absolute;background-position: center center;top:2px;height:16px;width:16px;left:2px;background-image:url(" + stateimg + ")'></div>";
                }
                popupdiv += "<div class='popup_header' style='position:absolute;top:2px;height:18px;left:20px'>" + CommonTools.htmlspecialchars(annot.GetTitle()) + "</div>";
                popupdiv += "</div>";
                //end title div

                //content div
                var content_color = "rgb(255, 255, 255)";
                if (annot.GetColor() === "#ffffff") {
                    content_color = "rgb(240, 240, 240)";
                }
                popupdiv += "<div class='popup_child' style='overflow: auto; background-color: " + content_color + ";white-space: pre-wrap; position: absolute; left: 4px; top:40px; width: " + (pop_width - 8) + "px; bottom:10px;'>"; // (pop_height - 55)
                popupdiv += "<div class='popup_child' style='position:relative;padding:2px;clear:both;left: 0px; top: 0px;'>";
                popupdiv += "<div class='popup_child' style='clear:both;padding-top:2px;padding-bottom:2px;word-wrap: break-word; word-break: normal;color:#000'>" + CommonTools.htmlspecialchars(annot.GetContents()) + "</div>";
                popupdiv += "</div>";
                popupdiv += _CreateReplyChainHtmlContent(annot);
                //end content div 
                popupdiv += "</div>";
                //end popup div
                popupdiv += "</div>";
                annotDivStr += popupdiv;
            }

            return annotDivStr;
        };

        function _CreateAnnotsHtmlContent(pPageView) {
            if (!pPageView)
                return '';
            var pPDFPage = pPageView.GetPDFPage();
            var iAnnotCnt = pPDFPage.GetAnnotCount();
            var szAnnotsHtml = "<div id='" + _self.GetPageAnnotsContainerID(pPageView) + "'>";
            for (var i = 0; i < iAnnotCnt; i++) {
                var annot = pPDFPage.GetAnnot(i);
                var annotDivStr = _self.CreateAAnnotHtmlContent(pPageView, annot, i);
                szAnnotsHtml += annotDivStr;
            }
            szAnnotsHtml += "</div>";
            return szAnnotsHtml;
        }
        //更新Annot的位置;
        function _UpdateAnnotsPosition(pPageView, visableRect) {
            var pPDFPage = pPageView.GetPDFPage();
            var iAnnotCnt = pPDFPage.GetAnnotCount();
            for (var i = 0; i < iAnnotCnt; i++) {
                var annot = pPDFPage.GetAnnot(i);
                if (_PageAnnotUpdatedList[pPageView.GetPageIndex()] == false) {
                    var annotPDFRect = annot.GetRect();
                    var annotDocRect = pPageView.PDF2Doc(annotPDFRect, true);
                    var annotDivID = _self.GetAnnotDivID(pPageView, i);
                    $("#" + annotDivID).css({
                        left: annotDocRect.left,
                        top: annotDocRect.top,
                        width: FXREADER.RectUtils.Width(annotDocRect),
                        height: FXREADER.RectUtils.Height(annotDocRect)
                    });
                }
                if (annot.GetType() === "Markup") {
                    var popup = annot.GetPopup();
                    if (popup == null)
                        continue;
                    var popupDivID = _self.GetAnnotPopupDivID(pPageView, i);
                    var popupPDFRect = popup.GetRect();
                    //注意参数bScale设为false
                    var popupDocRect = pPageView.PDF2Doc(popupPDFRect, false);
                    var width = FXREADER.RectUtils.Width(popupDocRect);
                    var height = FXREADER.RectUtils.Height(popupDocRect);
                    var visableWidth = FXREADER.RectUtils.Width(visableRect);
                    var visableHeight = FXREADER.RectUtils.Height(visableRect);
                    if (popupDocRect.top < visableRect.top) {
                        popupDocRect.top = visableRect.top;
                        popupDocRect.bottom = popupDocRect.top + height;
                    }

                    if (popupDocRect.bottom > visableRect.bottom) {
                        popupDocRect.bottom = visableRect.bottom;
                        popupDocRect.top = popupDocRect.bottom - height;
                    }
                    if (popupDocRect.left < visableRect.left) {
                        popupDocRect.left = visableRect.left;
                        popupDocRect.right = popupDocRect.left + width;
                    }
                    if (popupDocRect.right > visableRect.right) {
                        popupDocRect.right = visableRect.right;
                        if (popupDocRect.right - width > visableRect.left)
                            popupDocRect.left = popupDocRect.right - width;
                        if (popupDocRect.left >= popupDocRect.right)
                            popupDocRect.left = popupDocRect.right - width;
                        if (popupDocRect.left < visableRect.left)
                            popupDocRect.left = visableRect.left;
                    }


                    $("#" + popupDivID).css({
                        left: popupDocRect.left,
                        top: popupDocRect.top,
                        width: FXREADER.RectUtils.Width(popupDocRect),
                        height: FXREADER.RectUtils.Height(popupDocRect)
                    });
                }
            }
        }


        /**
        * 获取当前页面的Annot的显示区域范围.
        * @param [pPageView] 页面视图对象;
        * @param [contentPanelOffset] 文档可视区域的偏移量   {top:xx,left:xx};
        * @param [contentPanelWidth] 文档可视区域宽度;
        * @param [contentPaneHeight] 文档可视区域高度;
        */
        function _GetAnnotVisableRect(pPageView, contentPanelOffset, contentPanelWidth, contentPaneHeight) {
            var page_width = pPageView.GetPageViewWidth(),
                  page_height = pPageView.GetPageViewHeight(),
                  iPageNum = pPageView.GetPageIndex();
            var jqPageContainer = $("#" + pPageView.GetPageContainerID());
            var ScrollApi = pPageView.GetDocView().GetScrollApi();
            var visableWidth = contentPanelWidth;
            var visableHeight = contentPaneHeight;
            var page_pos = jqPageContainer.offset();

            if (ScrollApi != null) {
                //减去滚动条高度;
                if (ScrollApi.getIsScrollableH())
                    visableHeight -= 22;
                //减去滚动条宽度;
                if (ScrollApi.getIsScrollableV())
                    visableWidth -= 22;
            }

            var visableRect = new FXREADER.CPDF_Rect(0, 0, 0, 0);
            var bottomCuted = page_pos.top + page_height - (contentPanelOffset.top + visableHeight);
            if (bottomCuted < 0)
                bottomCuted = 0;
            //在显示区域上部分;
            if ((page_pos.top < contentPanelOffset.top)) {
                //相对页面顶部的偏移;
                visableRect.top = contentPanelOffset.top - page_pos.top;
                visableRect.bottom = visableRect.top + page_height - (contentPanelOffset.top - page_pos.top) - bottomCuted;
            }
            else {
                visableRect.top = 0;
                //第一页,相对页面顶部的偏移;
                if (iPageNum == 0)
                    visableRect.top = contentPanelOffset.top - page_pos.top;
                visableRect.bottom = page_height - bottomCuted;
            }
            //如果是最后一页
            if (iPageNum == pPageView.GetDocView().GetPageCount() - 1) {
                if (page_pos.top + page_height < contentPanelOffset.top + visableHeight)
                    visableRect.bottom += (contentPanelOffset.top + visableHeight) - (page_pos.top + page_height);
            }


            if (pPageView.GetDocView().GetViewMode() == FXREADER.PDFView.RD_BRMODE_CONTINUOUS_FACING) {
                //减去11是减去左右两个面板的间距
                var pagePanelWidth = (visableWidth) / 2 - 11;
                //左侧面板.
                if (iPageNum % 2 == 0) {
                    visableRect.left = contentPanelOffset.left - page_pos.left + 1;
                    var right_cutted = page_pos.left + page_width - (contentPanelOffset.left + visableWidth);
                    visableRect.right = page_width - 1;
                    if (right_cutted > 0)
                        visableRect.right -= right_cutted;
                }
                else {
                    visableRect.left = 0;
                    visableRect.right = visableRect.left + pagePanelWidth;
                    var right_cutted = page_pos.left + page_width - (contentPanelOffset.left + visableWidth);
                    if (right_cutted > 0) {
                        visableRect.right = page_width - right_cutted;
                    }

                }
            }
            else if (pPageView.GetDocView().GetViewMode() == FXREADER.PDFView.RD_BRMODE_CONTINUOUS) {
                visableRect.left = contentPanelOffset.left - page_pos.left + 1;
                visableRect.right = visableRect.left + visableWidth;
            }
            return visableRect;
        }


        /////////////////////////////////////////////////////////////////////////////////////////////////

        //public methods
        //获取Plugin名称
        this.GetPluginName = function () {
            return "Annot Plugin";
        };
        //模块初始化;
        this.PIInit = function () {
            var pAnnotPageEventHandler = new CAnnot_PageEventHandler(_self);
            var pAnnotMousePtHandler = new CAnnot_MousePtHandler(_self);
            _pReaderApp.RegisterPageEventHandler(pAnnotPageEventHandler);
            _pReaderApp.RegisterMousePtHandler(pAnnotMousePtHandler);
            var pAnnotDocViewEventHandler = new CAnnot_DocViewEventHandler(_self);
            _pReaderApp.RegisterDocViewEventHandler(pAnnotDocViewEventHandler);
            _self.ResetAnnotUpdatedList();
            _self.GetAnnotData(FXREADER.Config.requestRetryCount);
            _self.BindAnnotEvents();
        };

        //插件被注册的时候调用;
        this.PIOnRegister = function () {
        };

        //模块卸载;
        this.PIUnload = function () {
        };

        this.GetReaderApp = function () {
            return _pReaderApp;
        };

        //从网络上获取Annot数据;
        this.GetAnnotData = function (retryCount) {
        	 if (retryCount <= 0) {
                 throw new Error('Maximum number of retries exceeded for GetAnnotData request.');
             }
            var data = { fileid: pReaderApp.GetFileID(), fname: pReaderApp.GetFileName() };
            $.ajax({
                url: FXREADER.Config.Url.GetAnnotData,
                type: 'POST',
                dataType: 'json',
                data: data,

                success: function (response) {
                    var error = response.error;
                    if (error != 0) {
                    	 if (FXREADER.Common.IsNeedRetry(response.status)) {
                    		 var interval = FXREADER.AjaxRetryManager.GetNextAnnotDataRequestInterval(_self.GetReaderApp().GetMainView().GetDocView().GetPageCount());
                             setTimeout(function () { _self.GetAnnotData(retryCount - 1); }, interval);
                             return;
                         }
                         else {
                             throw new Error('Get Annot Data Error:' + error);
                             return;
                         }
                    }
                    try {
                        var jsonAnnotData = $.parseJSON(response.AnnotData);
                        //初始化Annot;
                        if (jsonAnnotData != null) {
                            _pReaderApp.StepProgress();
                            _Init(jsonAnnotData);
                        }
                    }
                    catch (ex) {
                        throw ex;
                        return false;
                    }
                },
                error: function () {
                    throw new Error('Get Annot Data Error!');
                }
            });

        };

        //////////////////////////////////生成Annot对应Html标签相关////////////////////////////////////////
        this.GetAnnotDivID = function (pPageView, iAnnotIndex) {
            return pPageView.GetPageContainerID() + "_Annots_" + iAnnotIndex.toString();
        };

        this.GetAnnotPopupDivID = function (pPageView, iAnnotIndex) {
            return pPageView.GetPageContainerID() + "_Popup_" + iAnnotIndex.toString();
        };

        this.GetPageAnnotsContainerID = function (pPageView) {
            return pPageView.GetPageContainerID() + "_AnnotsContainer";
        };

        this.GetDocView = function () {
            return _pReaderApp.GetMainView().GetDocView();
        };

        this.BindAnnotEvents = function () {
            //绑定普通Annot事件
            $('.fwr_annot').live('mousedown mouseover mouseout', function (event) {
                if (event.type == 'mousedown') {
                    try {
                        var nPageIndex = parseInt(event.target.getAttribute("page-index"));
                        var nAnnotIndex = parseInt(event.target.getAttribute("annot-index"));
                        var pDocView = _self.GetReaderApp().GetMainView().GetDocView();
                        var pPageView = pDocView.GetPageView(nPageIndex);
                        var pPDFPage = pPageView.GetPDFPage();
                        var annot = pPDFPage.GetAnnot(nAnnotIndex);
                        if (annot != null) {
                            switch (annot.GetType()) {
                                case "Link":
                                    {
                                        var action = annot.GetAction();
                                        if (action != null) {
                                            switch (action.GetActionType()) {
                                                case "GoTo":
                                                    var dest = action.GetDest();
                                                    if (dest != null) {
                                                        pDocView.GotoPageByDest(dest);
                                                        return true;
                                                    }
                                                    break;
                                                case "URI":
                                                    break;
                                                default: break;
                                            }

                                        }
                                        else {
                                            var dest = annot.GetDestination();
                                            if (dest != null) {
                                                pDocView.GotoPageByDest(dest);
                                                return true;
                                            }
                                        }
                                    }
                                    break;
                                case "Markup":
                                    {
                                        _curVisableRope.nPageIndex = -1;
                                        _curVisableRope.nAnnotIndex = -1;
                                        var pAncestorAnnot = annot.GetHeadAncestorAnnot();
                                        if (pAncestorAnnot != null) {
                                            var nAncestorAnnotIndex = pPDFPage.GetAnnotIndex(pAncestorAnnot);
                                            if (_self.ChangePopupAnnotState(pPageView, nAncestorAnnotIndex) == 1) {
                                                _curVisableRope.nPageIndex = nPageIndex;
                                                _curVisableRope.nAnnotIndex = nAncestorAnnotIndex;
                                            }
                                        }
                                        else {
                                            if (_self.ChangePopupAnnotState(pPageView, nAnnotIndex) == 1) {
                                                _curVisableRope.nPageIndex = nPageIndex;
                                                _curVisableRope.nAnnotIndex = nAnnotIndex;
                                            }
                                        }
                                        _self.OnDraw();
                                        return true;

                                    }
                                    break;
                                default: break;
                            }
                        }
                    }
                    catch (err) {
                        throw err;
                        return false;
                    }
                } else if (event.type == 'mouseover') {
                    try {
                        var nPageIndex = parseInt(event.target.getAttribute("page-index"));
                        var nAnnotIndex = parseInt(event.target.getAttribute("annot-index"));
                        var pDocView = _self.GetReaderApp().GetMainView().GetDocView();
                        var pPageView = pDocView.GetPageView(nPageIndex);
                        var pPDFPage = pPageView.GetPDFPage();
                        var annot = pPDFPage.GetAnnot(nAnnotIndex);
                        if (annot != null) {
                            switch (annot.GetType()) {
                                case "Markup":
                                    {
                                        var pAncestorAnnot = annot.GetHeadAncestorAnnot();
                                        if (pAncestorAnnot != null) {
                                            var nAncestorAnnotIndex = pPDFPage.GetAnnotIndex(pAncestorAnnot);
                                            _curVisableRope.nPageIndex = nPageIndex;
                                            _curVisableRope.nAnnotIndex = nAncestorAnnotIndex;
                                        }
                                        else {
                                            _curVisableRope.nPageIndex = nPageIndex;
                                            _curVisableRope.nAnnotIndex = nAnnotIndex;
                                        }
                                        _self.OnDraw();
                                        return true;

                                    }
                                    break;
                                default: break;
                            }
                        }
                    }
                    catch (err) {
                        throw err;
                        return false;
                    }
                }
                else {
                    try {
                        _curVisableRope.nPageIndex = -1;
                        _curVisableRope.nAnnotIndex = -1;
                        _self.OnDraw();
                        return true;
                    }
                    catch (err) {
                        throw err;
                        return false;
                    }
                }

            });
            //绑定关闭按钮事件;
            $('.annot_close_btn').live('mousedown', function (event) {
                try {
                    var nPageIndex = parseInt(event.target.parentNode.parentNode.getAttribute("page-index"));
                    var nAnnotIndex = parseInt(event.target.parentNode.parentNode.getAttribute("annot-index"));
                    var pPageView = _self.GetReaderApp().GetMainView().GetDocView().GetPageView(nPageIndex);
                    //var pPDFPage = pPageView.GetPDFPage();
                    _self.HidePopupAnnot(pPageView, nAnnotIndex);
                    return true;
                }
                catch (err) {
                    throw err;
                    return false;
                }
            });
            //绑定popup annot事件;
            $('.fwr_popup_annot').live('mouseenter mouseleave', function (event) {
                //jquery 1.4.1响应的是mouseenter和mouseleave
                //jquery 1.4.2响应的是mouseover和mouseout
                //这里用jquery1.4.2所以 用mouseover而不是mouseenter;
                if (event.type == 'mouseover') {
                    try {
                        var nPageIndex = parseInt(event.currentTarget.getAttribute("page-index"));
                        var nAnnotIndex = parseInt(event.currentTarget.getAttribute("annot-index"));
                        _curVisableRope.nPageIndex = nPageIndex;
                        _curVisableRope.nAnnotIndex = nAnnotIndex;
                        _self.OnDraw();
                        return true;
                    }
                    catch (err) {
                        throw err;
                        return false;
                    }
                }
                else {
                    try {
                        _curVisableRope.nPageIndex = -1;
                        _curVisableRope.nAnnotIndex = -1;
                        _self.OnDraw();
                        return true;
                    }
                    catch (err) {
                        throw err;
                        return false;
                    }
                }

            });
        };

        this.ShowAnnots = function (pPageView, bShow) {
            var jqAnnots = $("#" + _self.GetPageAnnotsContainerID(pPageView));
            bShow ? jqAnnots.show() : jqAnnots.hide();
        };

        this.HidePopupAnnot = function (pPageView, nAnnotIndex) {
            var pPDFPage = pPageView.GetPDFPage();
            var annot = pPDFPage.GetAnnot(nAnnotIndex);
            if (annot == null)
                return;
            var popup = annot.GetPopup();
            if (popup == null)
                return;
            var id = _self.GetAnnotPopupDivID(pPageView, nAnnotIndex);
            var jqPopup = $("#" + id);
            if (jqPopup == null)
                return;
            jqPopup.hide();
            popup.SetOpenState(0);
        };

        //设置popup annot的显示状态，并返回设置后的状态，1表示显示，0表示隐藏;
        this.ChangePopupAnnotState = function (pPageView, nAnnotIndex) {
            var pPDFPage = pPageView.GetPDFPage();
            var annot = pPDFPage.GetAnnot(nAnnotIndex);
            if (annot == null)
                return 0;
            var popup = annot.GetPopup();
            if (popup == null)
                return 0;
            var id = _self.GetAnnotPopupDivID(pPageView, nAnnotIndex);
            var jqPopup = $("#" + id);
            if (jqPopup == null)
                return 0;
            if (popup.GetOpenState() === 0) {
                jqPopup.show();
                popup.SetOpenState(1);
                return 1;
            }
            else {
                jqPopup.hide();
                popup.SetOpenState(0);
                return 0;
            }
        };

        this.MovePopupAnnot = function (iPageIndex, iAnnotIndex, offsetX, offsetY) {
            var pDocView = _self.GetReaderApp().GetMainView().GetDocView();
            var pPageView = pDocView.GetPageView(iPageIndex);
            if (!pPageView)
                return false;
            var pPDFPage = pPageView.GetPDFPage();
            var annot = pPDFPage.GetAnnot(iAnnotIndex);
            if (!annot)
                return false;
            if (annot.GetType() != "Markup")
                return false;
            var popup = annot.GetPopup();
            if (popup == null)
                return false;
            var popupDivID = _self.GetAnnotPopupDivID(pPageView, iAnnotIndex);
            var jqPopup = $("#" + popupDivID);
            var popupPDFRect = popup.GetRect();
            var nPt2Pixel = pDocView.GetPageViewRender().GetPixelsPerPoint();
            FXREADER.RectUtils.Offset(popupPDFRect,offsetX / pPageView.GetScale() / nPt2Pixel, -offsetY / pPageView.GetScale() / nPt2Pixel);
            popup.SetRect(popupPDFRect);
            var jqPagesContainerDiv = $("#" + pDocView.GetDocViewContainerID());
            var contentPaneHeight = jqPagesContainerDiv.height();
            var contentPanelWidth = jqPagesContainerDiv.width();
            var contentPanelOffset = jqPagesContainerDiv.offset();
            var rcAnnotVisableRect = _GetAnnotVisableRect(pPageView, contentPanelOffset, contentPanelWidth, contentPaneHeight);
            _UpdateAnnotsPosition(pPageView, rcAnnotVisableRect);
        };

        this.DrawAnnotRope = function (iAnnotIndex, iPageIndex) {
            var pDocView = _self.GetReaderApp().GetMainView().GetDocView();
            var pPageView = pDocView.GetPageView(iPageIndex);
            if (!pPageView)
                return false;
            var canvas = document.getElementById(_AnnotCanvasID);
            if (canvas == null)
                return false;
            if (canvas == null)
                return false;
            var ctx = canvas.getContext("2d");
            if (ctx == null)
                return false;
            var pPDFPage = pPageView.GetPDFPage();
            var annot = pPDFPage.GetAnnot(iAnnotIndex);
            if (!annot)
                return false;
            if (annot.GetType() != "Markup")
                return false;
            var popup = annot.GetPopup();
            if (popup == null)
                return false;
            //处于关闭状态的不绘制;
            if (popup.GetOpenState() == 0)
                return false;
            var page_offset = pPageView.GetPageViewDivOffset();
            if (page_offset == null)
                return false;
            var jqCanvas = $(canvas);
            var posCanvas = jqCanvas.position();
            page_offset.left -= posCanvas.left;
            page_offset.top -= posCanvas.top;
            var annotDivID = _self.GetAnnotDivID(pPageView, iAnnotIndex);
            var jqAnnot = $("#" + annotDivID);
            var popupDivID = _self.GetAnnotPopupDivID(pPageView, iAnnotIndex);
            var jqPopup = $("#" + popupDivID);
            var annoPosition = jqAnnot.position();
            var popupPosition = jqPopup.position();
            if (annoPosition == null || popupPosition == null)
                return false;
            var annot_rect = new FXREADER.CPDF_Rect(annoPosition.left, annoPosition.top, jqAnnot.width() + annoPosition.left, jqAnnot.height() + annoPosition.top);
            var popup_rect = new FXREADER.CPDF_Rect(popupPosition.left, popupPosition.top, jqPopup.width() + popupPosition.left, jqPopup.height() + popupPosition.top);
            FXREADER.RectUtils.Offset(annot_rect,page_offset.left, page_offset.top);
            FXREADER.RectUtils.Offset(popup_rect,page_offset.left, page_offset.top);

            var rcShipCaption = new FXREADER.CPDF_Rect(popup_rect.left, popup_rect.top, popup_rect.right, popup_rect.top + 20);
            if (rcShipCaption.bottom > popup_rect.bottom)
                rcShipCaption.bottom = popup_rect.bottom;
            var tmpRect = new FXREADER.CPDF_Rect(0, 0, 0, 0);
            FXREADER.RectUtils.Copy(popup_rect, tmpRect);
            FXREADER.RectUtils.Normalize(tmpRect);
            var ptAnchor = new FXREADER.CPDF_Point((annot_rect.left + annot_rect.right) / 2, (annot_rect.top + annot_rect.bottom) / 2);
            if (FXREADER.RectUtils.PtInRect(tmpRect,ptAnchor))
                return false;

            var dbAngleFirst = ROPE_PI * 2.0;
            var dbAngleSecond = ROPE_PI * 2.0;
            var rcFirst = new FXREADER.CPDF_Rect(0, 0, 0, 0), rcSecond = new FXREADER.CPDF_Rect(0, 0, 0, 0), rcNew = new FXREADER.CPDF_Rect(0, 0, 0, 0);
            var ptFirst = new FXREADER.CPDF_Point(0, 0), ptSecond = new FXREADER.CPDF_Point(0, 0);
            if (ptAnchor.x < popup_rect.left) {
                rcFirst.left = ptAnchor.x;
                rcFirst.right = popup_rect.left;
                rcFirst.top = Math.min(ptAnchor.y, popup_rect.top);
                rcFirst.bottom = Math.max(ptAnchor.y, popup_rect.bottom);
                dbAngleFirst = Math.atan2((rcShipCaption.top + rcShipCaption.bottom) / 2.0 - ptAnchor.y, FXREADER.RectUtils.Width(rcFirst));
            }
            else if (ptAnchor.x > popup_rect.right) {
                rcFirst.left = popup_rect.right;
                rcFirst.right = ptAnchor.x;
                rcFirst.top = Math.min(ptAnchor.y, popup_rect.top);
                rcFirst.bottom = Math.max(ptAnchor.y, popup_rect.bottom);
                dbAngleFirst = Math.atan2((rcShipCaption.top + rcShipCaption.bottom) / 2.0 - ptAnchor.y, FXREADER.RectUtils.Width(rcFirst));
            }

            if (ptAnchor.y < popup_rect.top) {
                rcSecond.left = Math.min(ptAnchor.x, popup_rect.left);
                rcSecond.right = Math.max(ptAnchor.x, popup_rect.right);
                rcSecond.top = ptAnchor.y;
                rcSecond.bottom = popup_rect.top;
                dbAngleSecond = Math.atan2((popup_rect.left + popup_rect.right) / 2.0 - ptAnchor.x, FXREADER.RectUtils.Height(rcSecond));
            }
            else if (ptAnchor.y > popup_rect.bottom) {
                rcSecond.left = Math.min(ptAnchor.x, popup_rect.left);
                rcSecond.right = Math.max(ptAnchor.x, popup_rect.right);
                rcSecond.top = popup_rect.bottom;
                rcSecond.bottom = ptAnchor.y;

                dbAngleSecond = Math.atan2((popup_rect.left + popup_rect.right) / 2.0 - ptAnchor.x, FXREADER.RectUtils.Height(rcSecond));
            }

            if (Math.abs(dbAngleFirst) < Math.abs(dbAngleSecond)) {
                FXREADER.RectUtils.Copy(rcFirst, rcNew);
                if (ptAnchor.x < popup_rect.left) {
                    ptFirst.x = popup_rect.left;
                    ptSecond.x = popup_rect.left;
                }
                else {
                    ptFirst.x = popup_rect.right;
                    ptSecond.x = popup_rect.right;
                }

                var y = (rcShipCaption.top + rcShipCaption.bottom) / 2;
                var yStep = (ROPE_THICKNESS / (Math.cos(dbAngleFirst) * 2) + 0.5);

                ptFirst.y = y - yStep;
                ptSecond.y = y + yStep;

                ptFirst.y = Math.max(ptFirst.y, popup_rect.top);
                ptFirst.y = Math.min(ptFirst.y, popup_rect.bottom);
                ptSecond.y = Math.max(ptSecond.y, popup_rect.top);
                ptSecond.y = Math.min(ptSecond.y, popup_rect.bottom);
            }
            else {
                FXREADER.RectUtils.Copy(rcSecond, rcNew);
                if (ptAnchor.y < popup_rect.top) {
                    ptFirst.y = popup_rect.top;
                    ptSecond.y = popup_rect.top;
                }
                else {
                    ptFirst.y = popup_rect.bottom;
                    ptSecond.y = popup_rect.bottom;
                }

                var x = (popup_rect.left + popup_rect.right) / 2;
                var xStep = (ROPE_THICKNESS / (Math.cos(dbAngleSecond) * 2) + 0.5);

                ptFirst.x = x - xStep;
                ptSecond.x = x + xStep;

                ptFirst.x = Math.max(ptFirst.x, popup_rect.left);
                ptFirst.x = Math.min(ptFirst.x, popup_rect.right);
                ptSecond.x = Math.max(ptSecond.x, popup_rect.left);
                ptSecond.x = Math.min(ptSecond.x, popup_rect.right);
            }
            var annot_color = annot.GetColor();
            _self.DrawRope(ctx, ptAnchor.x, ptAnchor.y, ptFirst.x, ptFirst.y, ptSecond.x, ptSecond.y, "rgba(125,125,125,0.35)", "rgba(125,125,125,0.35)", 2.0);
            _self.DrawRope(ctx, ptAnchor.x, ptAnchor.y, ptFirst.x, ptFirst.y, ptSecond.x, ptSecond.y, FXREADER.Common.HexColor2Rgba(annot_color, 0.7), FXREADER.Common.HexColor2Rgba(annot_color, 1), 1.0);
            return true;
        };


        this.DrawRope = function (ctx, pt1_x, pt1_y, pt2_x, pt2_y, pt3_x, pt3_y, crFill, crStroke, nLineWidth) {
            if (ctx == null)
                return;
            ctx.save();
            var ptCenter_x = (pt1_x + pt2_x + pt3_x) / 3;
            var ptCenter_y = (pt1_y + pt2_y + pt3_y) / 3;
            ctx.beginPath();
            ctx.moveTo(pt1_x, pt1_y);
            var controlPt1_x = pt1_x + (ptCenter_x - pt1_x) * ROPE_SHAPE_FACTOR2;
            var controlPt1_y = pt1_y + (ptCenter_y - pt1_y) * ROPE_SHAPE_FACTOR2;

            var controlPt2_x = pt2_x + (ptCenter_x - pt2_x) * ROPE_SHAPE_FACTOR1;
            var controlPt2_y = pt2_y + (ptCenter_y - pt2_y) * ROPE_SHAPE_FACTOR1;
            ctx.bezierCurveTo(controlPt1_x, controlPt1_y, controlPt2_x, controlPt2_y, pt2_x, pt2_y);
            ctx.lineTo(pt3_x, pt3_y);

            var controlPt3_x = pt3_x + (ptCenter_x - pt3_x) * ROPE_SHAPE_FACTOR1;
            var controlPt3_y = pt3_y + (ptCenter_y - pt3_y) * ROPE_SHAPE_FACTOR1;
            var controlPt4_x = pt1_x + (ptCenter_x - pt1_x) * ROPE_SHAPE_FACTOR2;
            var controlPt4_y = pt1_y + (ptCenter_y - pt1_y) * ROPE_SHAPE_FACTOR2;
            ctx.bezierCurveTo(controlPt3_x, controlPt3_y, controlPt4_x, controlPt4_y, pt1_x, pt1_y);

            ctx.closePath();
            ctx.fillStyle = crFill;
            ctx.fill();
            ctx.strokeStyle = crStroke;
            ctx.lineWidth = nLineWidth;
            ctx.stroke();

            ctx.restore();
        };


        //清空画板并返回画板上下文指针;
        this.ClearCavans = function () {
            var CanvasElem = document.getElementById(_AnnotCanvasID);
            if (CanvasElem == null)
                return null;
            var ctx = CanvasElem.getContext("2d");
            //这里最好不要对整个画布进行清除;
            ctx.clearRect(0, 0, CanvasElem.width, CanvasElem.height);
            return ctx;
        };


        //重绘函数;
        this.OnDraw = function () {
            var ctx = _self.ClearCavans();
            if (ctx == null)
                return;
            if (_curVisableRope.nPageIndex != -1 && _curVisableRope.nAnnotIndex != -1) {
                var bDraw = _self.DrawAnnotRope(_curVisableRope.nAnnotIndex, _curVisableRope.nPageIndex);
            }
        };


        //重置Annot位置更新状态；
        this.ResetAnnotUpdatedList = function () {
            var iCnt = _pReaderApp.GetMainView().GetDocView().GetPDFDoc().GetPageCount();
            for (var i = 0; i < iCnt; i++) {
                _PageAnnotUpdatedList[i] = false;
            }
        };

        //Doc View 消息响应；
        this.OnDocViewResize = function () {
            _self.ResetAnnotUpdatedList();
            var CanvasElem = document.getElementById(_AnnotCanvasID);
            var pDocView = _pReaderApp.GetMainView().GetDocView();
            var ScrollApi = pDocView.GetScrollApi();
            var jqPagesContainerDiv = $("#" + pDocView.GetDocViewContainerID());
            if (CanvasElem != null) {
                CanvasElem.width = jqPagesContainerDiv.width();
                CanvasElem.height = jqPagesContainerDiv.height();
                var fleft = 0, ftop = 0;
                if (ScrollApi) {
                    fleft = ScrollApi.getContentPositionX();
                    ftop = ScrollApi.getContentPositionY();
                }
                $(CanvasElem).css({ top: ftop, left: fleft });
            }
        };

        this.OnPreDocViewResize = function () {
            var CanvasElem = document.getElementById(_AnnotCanvasID);
            if (CanvasElem != null) {
                //在重新初始化滚动条时，忽略canvas高度;
                CanvasElem.height = 0;
                CanvasElem.width = 0;
                $(CanvasElem).css({ left: 0, top: 0 });
            }
        };


        this.OnDocViewScroll = function () {
            var pDocView = _pReaderApp.GetMainView().GetDocView();
            var ScrollApi = pDocView.GetScrollApi();
            var CanvasElem = document.getElementById(_AnnotCanvasID);
            if (CanvasElem != null) {
                var fleft = 0, ftop = 0;
                if (ScrollApi) {
                    fleft = ScrollApi.getContentPositionX();
                    ftop = ScrollApi.getContentPositionY();
                }

                $(CanvasElem).css({ top: ftop, left: fleft });
            }
            this.OnDraw();
        };


        //PageEvent 消息响应;
        this.OnPageVisable = function (pPageView, contentPanelWidth, contentPanelHeight, contentPanelOffset) {
            if (pPageView == null || !_bInited)
                return false;
            if (!_PageAnnotCreatedList[pPageView.GetPageIndex()]) {
                if (!pPageView.IsPageLoaded())
                    return false;
                var annotHtml = _CreateAnnotsHtmlContent(pPageView);
                $("#" + pPageView.GetPageContainerID()).append(annotHtml);
                _PageAnnotCreatedList[pPageView.GetPageIndex()] = true;
            }

            var rcAnnotVisableRect = _GetAnnotVisableRect(pPageView, contentPanelOffset, contentPanelWidth, contentPanelHeight);
            _UpdateAnnotsPosition(pPageView, rcAnnotVisableRect);
            _PageAnnotUpdatedList[pPageView.GetPageIndex()] = true;
            this.ShowAnnots(pPageView, true);
            return true;
        };

        this.OnPageShowComplete = function (pPageView) {
            if (pPageView == null || !_bInited)
                return false;
            //var iPageIndex = pPageView.GetPageIndex();
            if (pPageView.IsPageLoadError()) {
                return false;
            }
            if (_PageAnnotCreatedList[pPageView.GetPageIndex()] == null) {
                var annotHtml = _CreateAnnotsHtmlContent(pPageView);
                $("#" + pPageView.GetPageContainerID()).append(annotHtml);
                _PageAnnotCreatedList[pPageView.GetPageIndex()] = true;
            }

            var jqPagesContainerDiv = $("#" + _pReaderApp.GetMainView().GetDocView().GetDocViewContainerID());
            var contentPanelHeight = jqPagesContainerDiv.height(); // $('#mainContainer').height();
            var contentPanelWidth = jqPagesContainerDiv.width();
            var contentPanelOffset = jqPagesContainerDiv.offset();
            this.OnPageVisable(pPageView, contentPanelWidth, contentPanelHeight, contentPanelOffset);

            return true;
        };

        this.OnPageInvisible = function (pPageView) {
            this.ShowAnnots(pPageView, false);
            return true;
        };
        
        this.OnDocViewZoom = function(scale)
        {
        	
        };
    };

    exports.Reader_CreatePlugin = function (pReaderApp) {
        var pAnnotPlugin = new FXREADER.CAnnotPlugin(pReaderApp);
        return pAnnotPlugin;
    };
});